home *** CD-ROM | disk | FTP | other *** search
- /************************************************************************/
- /* Module : db.c */
- /* Purpose: database module */
- /* By : Keith R. Davis */
- /* Date : 12/11/95 */
- /* Notes : Copyright(c) 1996 Whit River Software */
- /* Copyright(c) 1994, Regents of the University of California */
- /************************************************************************/
-
- #include <Xm/Xm.h> /* motif lib header */
- #include <Xm/CutPaste.h> /* motif clipboard header */
- #include <Xm/Text.h> /* text widget header */
- #include <X11/cursorfont.h> /* X cursors */
- #include <string.h> /* string header */
- #include <stdio.h> /* stdio header */
- #include <pwd.h> /* passwd header */
-
- #include "mquel.h" /* mquel module header */
- #include "llist.h" /* linked list header */
- #include "db.h" /* db data header */
- #include "util.h" /* utility function header */
-
- /* databse globals , this needs to be eliminated !! */
-
- PGconn *db = NULL; /* db ptr */
- char dbname[DB_NAME_SZ]; /* db name */
- char host[HOST_NAME_SZ]; /* host name */
- char port[PORT_NAME_SZ]; /* port */
- char spool_file[MAX_PATH_LEN]; /* spool file */
- char printer[PRINT_NAME_SZ]; /* printer */
- int col_width; /* default column width */
- int connected = 0; /* connect flag */
-
-
- /************************************************************************/
- /* Function: DB_Connect */
- /* Purpose : establishes connection to postgres database */
- /* Params : */
- /* Returns : 1 on SUCCESS / 0 on FAILURE */
- /* Notes : */
- /************************************************************************/
-
- int DB_Connect(void)
- {
- char db_msg[ERR_MSG_SIZE];
-
- DB_Grab();
-
- if(connected)
- PQfinish(db);
-
- db = PQsetdb(host, port, NULL, NULL, dbname);
-
- if (PQstatus(db) == CONNECTION_BAD) {
-
- sprintf(db_msg,"Connection to database '%s' failed.\nERROR: %s",
- dbname, PQerrorMessage(db));
- ErrorMsg("Connect", db_msg);
- sprintf(db_msg,"Not connected.");
- XtVaSetValues(AppWidgetsPtr->message,
- XtVaTypedArg, XmNlabelString, XmRString,
- db_msg, strlen(db_msg)+1, NULL);
- connected = 0;
- DB_UnGrab();
- return 0;
- }
- sprintf(db_msg,"Connected to database '%s'.", dbname);
- connected = 1;
- XtVaSetValues(AppWidgetsPtr->message,
- XtVaTypedArg, XmNlabelString, XmRString,
- db_msg, strlen(db_msg)+1, NULL);
-
- DB_UnGrab();
-
- return 1;
- }
-
- /************************************************************************/
- /* Function: DB_Close */
- /* Purpose : kills connection to postgres database */
- /* Params : */
- /* Returns : */
- /* Notes : */
- /************************************************************************/
-
- void DB_Close(void)
- {
- /* disconnect from database */
- if(connected)
- PQfinish(db);
- }
-
- /************************************************************************/
- /* Function: DB_SubmitQy */
- /* Purpose : submits SQL window contents to postgres database */
- /* Params : */
- /* Returns : 1 on SUCCESS / 0 on FAILURE */
- /* Notes : */
- /************************************************************************/
-
- int DB_SubmitQy(void)
- {
- char *qy_ptr;
- int buf_pos;
- int qy_pos;
- int qy_len;
- int selected = 0;
- char db_msg[ERR_MSG_SIZE];
- char qy_buffer[QY_BUFFER_SIZE];
- PGresult* results;
- PGnotify* notify;
-
- if (!connected) {
- sprintf(db_msg,"No Connection to database.");
- ErrorMsg("Query", db_msg);
- return 0;
- }
-
- if((char*)XmTextGetSelection(AppWidgetsPtr->sqlwindow)!= NULL){
- qy_ptr = (char*)doubleTrim((char*)XmTextGetSelection(AppWidgetsPtr->sqlwindow));
- selected = 1;
- }
- else
- qy_ptr = (char*)doubleTrim((char*)XmTextGetString(AppWidgetsPtr->sqlwindow));
-
- if((qy_len = strlen(qy_ptr)) == 0){
- if(selected)
- XtFree(qy_ptr);
- return 0;
- }
-
- qy_pos = 0;
-
- DB_Grab();
-
- while(qy_pos < qy_len){
- buf_pos = 0;
-
- while((qy_ptr[qy_pos] != ';') && (qy_pos < qy_len)){
- qy_buffer[buf_pos++] = qy_ptr[qy_pos++];
- if(strlen(qy_buffer) > (QY_BUFFER_SIZE - 2)){
- sprintf(db_msg,"Query length exceeds max. query size, truncated at %d\n",
- QY_BUFFER_SIZE);
- DB_WriteToResult(db_msg, 0, NULL);
- break;
- }
- }
-
- qy_pos++;
- qy_buffer[buf_pos++] = ';';
- qy_buffer[buf_pos] = '\0';
-
- results = PQexec(db, (char*)doubleTrim(qy_buffer));
- if (results == NULL) {
- DB_UnGrab();
- DB_WriteToResult(PQerrorMessage(db), 0, NULL);
- return 0;
- }
-
- switch (PQresultStatus(results)) {
- case PGRES_TUPLES_OK:
- DB_PrintTuples(qy_buffer,
- results,
- spool_file,
- XmToggleButtonGetState(AppWidgetsPtr->tglspool),
- XmToggleButtonGetState(AppWidgetsPtr->tglcol),
- XmToggleButtonGetState(AppWidgetsPtr->tglecho),
- col_width,
- GetColSeparator()
- );
- PQclear(results);
- break;
- case PGRES_EMPTY_QUERY:
- /* do nothing */
- break;
- case PGRES_COMMAND_OK:
- sprintf(db_msg,"%s\n\n",PQcmdStatus(results));
- DB_WriteToResult(db_msg, 0, NULL);
- break;
- case PGRES_COPY_OUT:
- DB_HandleCopyOut(results);
- PQclear(results);
- break;
- case PGRES_COPY_IN:
- DB_HandleCopyIn(results);
- PQclear(results);
- break;
- case PGRES_NONFATAL_ERROR:
- case PGRES_FATAL_ERROR:
- case PGRES_BAD_RESPONSE:
- DB_WriteToResult(PQerrorMessage(db), 0, NULL);
- break;
- }
-
- /* check for asynchronous returns */
- notify = PQnotifies(db);
- if (notify) {
- sprintf(db_msg,"ASYNC NOTIFY of '%s' from backend pid '%d' received",
- notify->relname, notify->be_pid);
- DB_WriteToResult(db_msg, 0, NULL);
- free(notify);
- }
- }
- if(selected)
- XtFree(qy_ptr);
- DB_UnGrab();
- return 1;
- }
-
- /************************************************************************/
- /* Function: DB_OpenFile */
- /* Purpose : opens a file into the SQL window */
- /* Params : file : string w/ filename */
- /* Returns : 1 on SUCCESS / 0 on FAILURE */
- /* Notes : */
- /************************************************************************/
-
- int DB_OpenFile(char *file)
- {
- FILE *sqlf;
- char db_msg[ERR_MSG_SIZE];
- char dataString[DATA_SIZE];
- XmTextSource txt_src;
- LLISTbuffer *tmp_buffer;
-
- if((sqlf = fopen(file, "rw")) == NULL){
- sprintf(db_msg, "Error opening: %s", file);
- ErrorMsg("Open File", db_msg);
- return 0;
- }
-
- if((tmp_buffer = LLIST_Insert(0, file, buffer_tail)) == NULL){
- sprintf(db_msg, "Not enough memory to open file :\n%s", file);
- ErrorMsg("Open File", db_msg);
- return 0;
- }
-
- DB_Grab();
-
- while(fgets(dataString, sizeof(dataString), sqlf) != NULL){
- DB_WriteToBuffer(dataString, tmp_buffer->buffer);
- }
-
- DB_UnGrab();
-
- if(fclose(sqlf) != 0){
- sprintf(db_msg, "Error closing file:\n%s", file);
- ErrorMsg("Open File", db_msg);
- return 0;
- }
-
- buffer_curr = DB_SetBuffer(tmp_buffer);
- return 1;
- }
-
- /************************************************************************/
- /* Function: DB_SaveFile */
- /* Purpose : saves a buffer into its source file */
- /* Params : buffer : ptr to buffer to save */
- /* Returns : 1 on SUCCESS / 0 on FAILURE */
- /* Notes : */
- /************************************************************************/
-
- int DB_SaveFile(LLISTbuffer *buffer)
- {
- FILE *sqlf;
- char *data;
- char db_msg[ERR_MSG_SIZE];
-
- if((sqlf = fopen(buffer->filename, "w+")) == NULL){
- sprintf(db_msg, "Error opening: %s", buffer->filename);
- ErrorMsg("Save", db_msg);
- return 0;
- }
-
- data = XmTextGetString(buffer->buffer);
-
- DB_Grab();
-
- fputs(data, sqlf);
- fflush(sqlf);
-
- DB_UnGrab();
-
- if(fclose(sqlf) != 0){
- sprintf(db_msg, "Error closing file: %s", buffer->filename);
- ErrorMsg("Save", db_msg);
- return 0;
- }
- buffer->modified = 0;
- DB_SetTitle(buffer->filename);
- sprintf(db_msg, "Saved file: %s", buffer->filename);
- XtVaSetValues(AppWidgetsPtr->message,
- XtVaTypedArg, XmNlabelString, XmRString,
- db_msg, strlen(db_msg)+1, NULL);
-
- return 1;
- }
-
- /************************************************************************/
- /* Function: DB_PrintTuples */
- /* Purpose : prints query results to selected destination */
- /* Params : qy : string w/ qy */
- /* res: query result struct */
- /* fout: string w/ file to write to */
- /* Spool: spooling flag 0=FALSE / 1=TRUE */
- /* PrintAttNames: print attribute names 0=FALSE / 1=TRUE */
- /* TerseOutput: print terse output 0=FALSE / 1=TRUE */
- /* Echo: echo query 0=FALSE / 1=TRUE */
- /* colWidth: width of output columns */
- /* Returns : */
- /* Notes : */
- /************************************************************************/
-
- void DB_PrintTuples(char *qy, PGresult *res, char *fout, int Spool, int PrintAttNames,
- int Echo, int colWidth, char sep)
- {
- FILE *spoolf;
- int nFields;
- int nTups;
- int i,j;
- char formatString[80];
- char dataString[DATA_SIZE];
-
- char *tborder = NULL;
-
- nFields = PQnfields(res);
- nTups = PQntuples(res);
-
- if(Spool){
- if((spoolf = fopen(fout, "w+")) == NULL){
- sprintf(dataString, "Error opening/creating file: %s\n", fout);
- DB_WriteToResult(dataString, 0, NULL);
- return;
- }
- }
-
- if(Echo){
- sprintf(dataString, "QUERY: %s\n\n",
- (char *)doubleTrim(qy));
- DB_WriteToResult(dataString, Spool, spoolf);
- }
-
- if (colWidth > 0) {
- if(sep == '\0')
- sprintf(formatString,"%%s%%-%ds", colWidth);
- else
- sprintf(formatString,"%%s%%-%ds%c", colWidth, sep);
- } else
- sprintf(formatString,"%%s%%s%c", sep);
-
- if ( nFields > 0 ) { /* only print tuples with at least 1 field. */
-
- if (PrintAttNames)
- {
- int width;
- width = nFields * colWidth;
- tborder = XtMalloc (width+1);
- for (i = 0; i <= width; i++)
- tborder[i] = '-';
- tborder[i] = '\0';
- }
-
- for (i=0; i < nFields; i++) {
- if (PrintAttNames) {
- sprintf(dataString,formatString,
- "", PQfname(res, i));
- if(i == (nFields - 1))
- dataString[strlen(dataString) - 1] = '\0';
- DB_WriteToResult(dataString, Spool, spoolf);
- }
- }
-
- if (PrintAttNames) {
- sprintf(dataString,"\n%s\n", tborder);
- DB_WriteToResult(dataString, Spool, spoolf);
- }
-
- for (i = 0; i < nTups; i++) {
- if(XmTextGetLastPosition(AppWidgetsPtr->resultwindow) > RSLT_BUFFER_SIZE)
- DB_ShrinkBuffer(AppWidgetsPtr->resultwindow);
-
- for (j = 0; j < nFields; j++) {
- char *pval = PQgetvalue(res,i,j);
- sprintf(dataString, formatString,
- "", pval ? pval : "");
- if(j == (nFields - 1))
- dataString[strlen(dataString) - 1] = '\0';
- DB_WriteToResult(dataString, Spool, spoolf);
- }
- sprintf(dataString,"\n");
- DB_WriteToResult(dataString, Spool, spoolf);
- }
- DB_WriteToResult("\n", Spool, spoolf);
- XtFree(tborder);
-
- if(Spool){
- if(fclose(spoolf) != 0){
- sprintf(dataString, "Error closing file: %s\n", fout);
- DB_WriteToResult(dataString, 0, NULL);
- return;
- }
- DB_WriteToResult("Query finished.\n", 0, NULL);
- }
- }
- }
-
- /************************************************************************/
- /* Function: DB_WriteToResult */
- /* Purpose : writes data to result window */
- /* Params : data : string w/ data to write */
- /* spool: spool flag 0=FALSE / 1=TRUE */
- /* file : spool file (FILE*) */
- /* Returns : */
- /* Notes : */
- /************************************************************************/
-
- void DB_WriteToResult(char *data, int spool, FILE *file)
- {
- XmTextPosition ins_pos;
-
- if(spool)
- fprintf(file, data);
- else{
- ins_pos = XmTextGetLastPosition(AppWidgetsPtr->resultwindow);
- XmTextInsert(AppWidgetsPtr->resultwindow, ins_pos, data);
- XmTextShowPosition(AppWidgetsPtr->resultwindow,
- XmTextGetLastPosition(AppWidgetsPtr->resultwindow)+1);
- }
- }
-
- /************************************************************************/
- /* Function: DB_WriteToSQL */
- /* Purpose : writes data to SQL window */
- /* Params : data : string w/ data to write */
- /* Returns : */
- /* Notes : */
- /************************************************************************/
-
- void DB_WriteToSQL(char *data)
- {
- XmTextPosition ins_pos;
-
- ins_pos = XmTextGetLastPosition(AppWidgetsPtr->sqlwindow);
- XmTextInsert(AppWidgetsPtr->sqlwindow, ins_pos, data);
- }
-
- /************************************************************************/
- /* Function: DB_WriteToBuffer */
- /* Purpose : writes data to text widget (buffer) */
- /* Params : data : string w/ data to write */
- /* w : text widget to write to (buffer) */
- /* Returns : */
- /* Notes : */
- /************************************************************************/
-
- void DB_WriteToBuffer(char *data, Widget w)
- {
- XmTextPosition ins_pos;
-
- ins_pos = XmTextGetLastPosition(w);
- XmTextInsert(w, ins_pos, data);
- }
-
- /************************************************************************/
- /* Function: DB_OpenScratchBuffer */
- /* Purpose : opens a new scratch buffer */
- /* Params : */
- /* Returns : ptr to new buffer on SUCCESS / NULL on FAILURE */
- /* Notes : */
- /************************************************************************/
-
- LLISTbuffer* DB_OpenScratchBuffer(void)
- {
- char db_msg[ERR_MSG_SIZE];
- LLISTbuffer *tmp_buffer;
-
- if((tmp_buffer = LLIST_Insert(0, "scratch", buffer_tail)) == NULL){
- sprintf(db_msg, "Not enough memory to open buffer.");
- ErrorMsg("New", db_msg);
- return NULL;
- }
- else
- return tmp_buffer;
- }
-
- /************************************************************************/
- /* Function: DB_SetBuffer */
- /* Purpose : sets a select buffer to current SQL window buffer */
- /* Params : buffer : ptr to buffer to display */
- /* Returns : ptr to new current buffer */
- /* Notes : */
- /************************************************************************/
-
- LLISTbuffer* DB_SetBuffer(LLISTbuffer *buffer)
- {
- XmTextSource sql_src;
- XmTextSource buffer_src;
-
- buffer_src = XmTextGetSource(buffer->buffer);
- XmTextSetSource(AppWidgetsPtr->sqlwindow, buffer_src, 0, 0);
-
- sql_src = XmTextGetSource(AppWidgetsPtr->sqlwindow);
- XmTextSetSource(buffer->buffer, sql_src, 0, 0);
-
- DB_SetTitle(buffer->filename);
-
- return buffer;
- }
-
- /************************************************************************/
- /* Function: DB_SetTitle */
- /* Purpose : sets app's title window to passed string */
- /* Params : win_title : string w/ window title */
- /* Returns : */
- /* Notes : */
- /************************************************************************/
-
- void DB_SetTitle(char *win_title)
- {
- char title[MAX_PATH_LEN]= "MPSQL - ";
-
- XtVaSetValues(AppWidgetsPtr->shell,
- XmNtitle, strcat(title, win_title),
- NULL);
-
- }
-
- /************************************************************************/
- /* Function: DB_DeleteBuffer */
- /* Purpose : deletes a buffer */
- /* Params : buffer : ptr to buffer to delete */
- /* Returns : */
- /* Notes : */
- /************************************************************************/
-
- void DB_DeleteBuffer(LLISTbuffer *buffer)
- {
- if((LLIST_Count() - 1) == 0){
- DB_OpenScratchBuffer();
- buffer_curr = DB_SetBuffer(buffer_tail->prev);
- }
- else{
- if(buffer->prev == buffer_head)
- buffer_curr = DB_SetBuffer(buffer->next);
- else
- buffer_curr = DB_SetBuffer(buffer->prev);
- }
- LLIST_Delete(buffer);
- }
-
- /************************************************************************/
- /* Function: DB_PrintBuffer */
- /* Purpose : prints contents of a buffer */
- /* Params : buffer : ptr to buffer to print */
- /* printer: ptr to printer command string to use */
- /* Returns : */
- /* Notes : */
- /************************************************************************/
-
- void DB_PrintBuffer(LLISTbuffer *buffer, char *printer)
- {
- char tmp_file[MAX_PATH_LEN];
- char tmp_name[MAX_PATH_LEN];
- char print[MAX_PATH_LEN];
- FILE *sqlf;
- char *data;
- char db_msg[ERR_MSG_SIZE];
-
- sprintf(tmp_file, "%s", tmpnam(tmp_name));
-
- if((sqlf = fopen(tmp_file, "w+")) == NULL){
- sprintf(db_msg, "Error opening tmp file: %s", tmp_file);
- ErrorMsg("Print", db_msg);
- return;
- }
-
- data = XmTextGetString(buffer->buffer);
-
- fputs(data, sqlf);
- fflush(sqlf);
-
- if(fclose(sqlf) != 0){
- sprintf(db_msg, "Error closing tmp file: %s", tmp_file);
- ErrorMsg("Print", db_msg);
- return;
- }
-
- sprintf(print, "%s %s",
- doubleTrim((char *)XmTextGetString(AppWidgetsPtr->printer)) ,tmp_file);
- system(print);
- sprintf(print, "rm -f %s", tmp_file);
- system(print);
- }
-
- /************************************************************************/
- /* Function: DB_ChkModBuffers */
- /* Purpose : checks the linked list for modified buffers */
- /* Params : */
- /* Returns : 0 all saved / 1 unsaved buffers */
- /* Notes : */
- /************************************************************************/
-
- int DB_ChkModBuffers(void)
- {
- int i;
- LLISTbuffer *curr;
-
- for(i = 1; i <= LLIST_Count(); i++){
- curr = LLIST_Get(i);
- if(curr->modified == 1)
- return 1;
- }
- return 0;
- }
-
- /************************************************************************/
- /* Function: DB_ShrinkBuffer */
- /* Purpose : removes text from top of specified text widget */
- /* Params : w : text widget to remove text from */
- /* Returns : nothing */
- /* Notes : */
- /************************************************************************/
-
- void DB_ShrinkBuffer(Widget w)
- {
- int i;
- char *txt = XmTextGetString(w);
-
- while(XmTextGetLastPosition(w) >= RSLT_BUFFER_SIZE){
- i = 0;
- while(txt[i] != '\n')
- i++;
- XmTextReplace(w, 0, ++i, "");
- }
- }
-
- /************************************************************************/
- /* Function: DB_HandleCopyOut */
- /* Purpose : copies data out as specified by passed copy command */
- /* Params : res: result set from copy command */
- /* Returns : nothing */
- /* Notes : */
- /************************************************************************/
-
- void DB_HandleCopyOut(PGresult *res)
- {
- bool copydone = false;
- char copybuf[COPYBUFSIZ];
- int ret;
-
- while (!copydone) {
- ret = PQgetline(res->conn, copybuf, COPYBUFSIZ);
-
- if (copybuf[0] == '.' && copybuf[1] =='\0') {
- copydone = true; /* don't print this... */
- } else {
- fputs(copybuf, stdout);
- switch (ret) {
- case EOF:
- copydone = true;
- case 0:
- fputc('\n', stdout);
- break;
- case 1:
- break;
- }
- }
- }
- fflush(stdout);
- PQendcopy(res->conn);
- }
-
- /************************************************************************/
- /* Function: DB_HandleCopyIn */
- /* Purpose : copies data in as specified by passed copy command */
- /* Params : res: result set from copy command */
- /* Returns : nothing */
- /* Notes : */
- /************************************************************************/
-
- void DB_HandleCopyIn(PGresult *res)
- {
- bool copydone = false;
- bool firstload;
- bool linedone;
- char copybuf[COPYBUFSIZ];
- char *s;
- int buflen;
- int c;
-
- fflush(stdin);
- if ((c = getc(stdin)) != '\n' && c != EOF) {
- (void) ungetc(c, stdin);
- }
-
- while (!copydone) { /* for each input line ... */
- firstload = true;
- linedone = false;
- while (!linedone) { /* for each buffer ... */
- s = copybuf;
- buflen = COPYBUFSIZ;
- for (; buflen > 1 &&
- !(linedone = (c = getc(stdin)) == '\n' || c == EOF);
- --buflen) {
- *s++ = c;
- }
- if (c == EOF) {
- /* reading from stdin, but from a file */
- PQputline(res->conn, ".");
- copydone = true;
- break;
- }
- *s = '\0';
- PQputline(res->conn, copybuf);
- if (firstload) {
- if (!strcmp(copybuf, ".")) {
- copydone = true;
- }
- firstload = false;
- }
- }
- PQputline(res->conn, "\n");
- }
- PQendcopy(res->conn);
- }
-
- /************************************************************************/
- /* Function: DB_Grab */
- /* Purpose : Grabs input events */
- /* Params : */
- /* Returns : nothing */
- /* Notes : */
- /************************************************************************/
-
- void DB_Grab(void)
- {
- XDefineCursor(XtDisplay(AppWidgetsPtr->mainwindow),
- XtWindow(AppWidgetsPtr->mainwindow),
- XCreateFontCursor(XtDisplay(AppWidgetsPtr->mainwindow),
- XC_watch));
-
- XtGrabButton(AppWidgetsPtr->mainwindow,
- AnyButton,
- AnyModifier,
- TRUE,
- ButtonPressMask|ButtonMotionMask|ButtonReleaseMask|
- LeaveWindowMask|EnterWindowMask|FocusChangeMask,
- GrabModeAsync,
- GrabModeAsync,
- None,
- None);
- }
-
- /************************************************************************/
- /* Function: DB_UnGrab */
- /* Purpose : UnGrabs input events */
- /* Params : */
- /* Returns : nothing */
- /* Notes : */
- /************************************************************************/
-
- void DB_UnGrab(void)
- {
- XtUngrabButton(AppWidgetsPtr->mainwindow, AnyButton, AnyModifier);
- XUndefineCursor(XtDisplay(AppWidgetsPtr->mainwindow),
- XtWindow(AppWidgetsPtr->mainwindow));
- }
-
-
-